Deploying Windows and Linux VMs

This tutorial shows how to create a number of VMs with mixed OS.

Specify the number of VMs

We expect to have 5 mixed VMs including 2 Windows Server VMs and 3 Ubuntu VMs.
NUM_W indicates the number of Windows VMs,
NUM_L indicates the number of Linux VMs below.

If you made changes, plese make sure you run the selected IPython Notebook cell by 'ctrl + Enter'


In [1]:
NUM_W = 2
NUM_L = 3

NUM = NUM_W + NUM_L

Initialize azure SDK

It is about setting credentials and obtaining access, etc. For the rest of the parts, there is not much thing that you have to change but it might be important to understand how it works.


In [58]:
from azure import *

In [59]:
import os
import json

class Credentials(object):
    '''
    Azure credentials needed to run Azure.
    '''
    def __init__(self):
        configFilename = os.environ["HOME"] + "/.azure/config.json"
        tmpName = os.path.join(os.getcwd(), configFilename)
        
        if not os.path.exists(tmpName):
            errMsg = "Cannot run Azure when the expected config file containing Azure credentials, '%s', does not exist!" % (tmpName)
            raise EnvironmentError(errMsg)

        with open(tmpName, "r") as f:
            self.ns = json.load(f)
        self.config_path = os.path.dirname(tmpName)

    def getManagementCertFile(self):
        try:
            return self.ns[u'managementcertfile'] 
        except:
            return self.config_path + "/managementCertificate.pem"
    def getSubscriptionId(self):
        return self.ns[u'subscriptionid'] 

    def getSubscription(self):
        return self.ns[u'subscription'] 
    
    def getServiceBusKey(self):
        return self.ns[u'servicebuskey'] 

    def getServiceBusNamespace(self):
        return self.ns[u'servicebusns']

    def getStorageServicesKey(self):
        return self.ns[u'storageserviceskey']

    def getStorageServicesName(self):
        return self.ns[u'storageservicesname']

    def getLinuxOSVHD(self):
        return self.ns[u'linuxosvhd']

    def getProxyHost(self):
        return self.ns[u'proxyhost']

    def getProxyPort(self):
        return self.ns[u'proxyport']

In [60]:
cert = Credentials()

subscription_id = cert.getSubscription()
certificate_path = cert.getManagementCertFile()

In [61]:
from azure.servicemanagement import *

sms = ServiceManagementService(subscription_id, certificate_path)

In [62]:
name = 'myvm-cluster-'
# In my case, I need to use 'Central US' location instead of 'West US' due to the location constraint of my subscription.
location = "Central US"

Get image names for Windows and Linux OS

linux_image_name will be set for an image name of latest Ubuntu 12.04
window_image_name will be set for an image name of Windows Server 2008 R2 SP1.


In [63]:
result = sms.list_os_images()
for image in result:
    if image.os == "Linux":
        if image.category == "Canonical":
            try:
                if image.label.index("12.04"):
                    linux_image_name = image.name
            except:
                pass
    elif image.os == "Windows":
        if image.category == "Microsoft Windows Server Group":
            try:
                if image.label.index("2008 R2 SP1"):
                    window_image_name = image.name
            except:
                pass

In [64]:
result = sms.list_storage_accounts()
for account in result:
    storage_account = account.service_name

In [65]:
container = "cluster"
blob_l = "ubuntu-12-04.vhd"
blob_w = "Win2K8R2SP1.vhd"

In [66]:
windows_blob_url = "blob.core.windows.net"
#media_link = "http://" + storage_account + "." + windows_blob_url + "/" + container + "/" + blob

In [67]:
#os_hd = OSVirtualHardDisk(image_name, media_link)

In [68]:
linux_user_id = 'azureuser'
linux_user_passwd = 'mypassword1234@'
linux_config = LinuxConfigurationSet(name, linux_user_id, linux_user_passwd, False)

In [69]:
window_user_passwd = linux_user_passwd
tzone = 'Pacific Standard Time'
window_config = WindowsConfigurationSet(computer_name=name, 
                                        admin_password=window_user_passwd, 
                                        reset_password_on_first_logon=False, 
                                        enable_automatic_updates=False, 
                                        time_zone=tzone)

In [70]:
azure_config = os.environ["HOME"] + '/.azure'
thumbprint_path = azure_config + '/.ssh/thumbprint'
authorized_keys = "/home/" + linux_user_id + "/.ssh/authorized_keys"

In [71]:
try:
    thumbprint=open(thumbprint_path, 'r').readline().split('\n')[0]
except:
    thumbprint=None

In [72]:
publickey = PublicKey(thumbprint, authorized_keys)
#keypair = KeyPair(thumbprint, key_pair_path)

linux_config.ssh.public_keys.public_keys.append(publickey)
#linux_config.ssh.key_pairs.key_pairs.append(keypair)

Configure certificate for Windows


In [73]:
window_config.domain_join = None
window_config.stored_certificate_settings.stored_certificate_settings.append(CertificateSetting(thumbprint=thumbprint, store_name='My', store_location='LocalMachine'))

In [74]:
network = ConfigurationSet()
network.configuration_set_type = 'NetworkConfiguration'
network.input_endpoints.input_endpoints.append(ConfigurationSetInputEndpoint('ssh', 'tcp', '22', '22'))

In [75]:
import base64
cert_data_path = azure_config + "/.ssh/myCert.pfx"
with open(cert_data_path, "rb") as bfile:
    cert_data = base64.b64encode(bfile.read())

In [76]:
cert_format = 'pfx'
cert_password = ''

In [77]:
from time import sleep

In [81]:
%time
results = []
results_cert = []
linux_cnt = 0
for num in range(NUM):
    new_name = name + str(num)
    if linux_cnt < NUM_L:
        image_name = linux_image_name
        blob = blob_l
        sys_config = linux_config
        linux_cnt += 1
        continue
    else:
        image_name = window_image_name
        blob = blob_w    
        sys_config = window_config
    media_link = "http://" + storage_account + "." + windows_blob_url + "/" + container + "/0-" + new_name + "-" + blob
    res = sms.create_hosted_service(service_name=new_name, label=new_name, location=location)
    sleep(5)
    os_hd = OSVirtualHardDisk(image_name, media_link)
    result_cert = sms.add_service_certificate(service_name=new_name,
                            data=cert_data,
                            certificate_format=cert_format,
                            password=cert_password)
    print new_name
    try:
        print vars(result_cert)
    except:
        print result_cert
    sleep(5)
    result = sms.create_virtual_machine_deployment(service_name=new_name,
        deployment_name=new_name,
        deployment_slot='production',
        label=new_name,
        role_name=new_name,
        system_config=sys_config,
        os_virtual_hard_disk=os_hd,
        network_config=network,
        role_size='Small')
    results.append(result)
    results_cert.append(result_cert)


CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
Wall time: 0.00 s
myvm-cluster-3
{'request_id': '5b46797d3fdf467eb25be36b309a7a7a'}
myvm-cluster-4
{'request_id': '34917e9844bb42feb3e63492ca2dc474'}

In [ ]:
for result in results:
    request_id = result.request_id
    status = sms.get_operation_status(request_id)
    try:
        print vars(status.error)
    except:
        print vars(status)